package owl2vowl.model.data;

import owl2vowl.model.data.AllEntityMap;
import owl2vowl.model.data.VowlGenerator;
import owl2vowl.model.data.VowlSearcher;
import owl2vowl.model.data.VowlThingProvider;
import owl2vowl.model.data.VowlIriGenerator;
import owl2vowl.model.entities.AbstractEntity;
import owl2vowl.model.entities.nodes.AbstractNode;
import owl2vowl.model.entities.nodes.classes.AbstractClass;
import owl2vowl.model.entities.nodes.classes.NullClass;
import owl2vowl.model.entities.nodes.datatypes.AbstractDatatype;
import owl2vowl.model.entities.nodes.datatypes.VowlLiteral;
import owl2vowl.model.entities.properties.AbstractProperty;
import owl2vowl.model.entities.properties.TypeOfProperty;
import owl2vowl.model.entities.properties.VowlDatatypeProperty;
import owl2vowl.model.entities.properties.VowlObjectProperty;
import owl2vowl.model.individuals.VowlIndividual;
import owl2vowl.model.ontology.OntologyInformation;
import owl2vowl.model.ontology.OntologyMetric;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLOntologyManager;

public class VowlData {
	private final VowlLiteral genericLiteral;
	protected OWLOntologyManager owlManager;
	private Map<AbstractEntity, String> entityToId = new HashMap();
	private Map<IRI, AbstractEntity> entityMap = new HashMap();
	private Map<IRI, AbstractClass> classMap;
	private Map<IRI, AbstractDatatype> datatypeMap;
	private Map<IRI, VowlObjectProperty> objectPropertyMap;
	private Map<IRI, VowlDatatypeProperty> datatypePropertyMap;
	private Map<IRI, TypeOfProperty> typeOfPropertyMap;
	private Map<IRI, VowlIndividual> individualMap;
	private OntologyInformation ontologyInformation;
	private Set<String> languages;
	private Set<IRI> baseIris;
	private VowlSearcher searcher;
	private VowlIriGenerator iriGenerator;
	private VowlGenerator generator;
	private VowlThingProvider thingProvider;
	private OntologyMetric metrics;

	public VowlData() {
      this.classMap = new AllEntityMap(this.entityMap);
      this.datatypeMap = new AllEntityMap(this.entityMap);
      this.objectPropertyMap = new AllEntityMap(this.entityMap);
      this.datatypePropertyMap = new AllEntityMap(this.entityMap);
      this.typeOfPropertyMap = new AllEntityMap(this.entityMap);
      this.individualMap = new HashMap();
      this.ontologyInformation = new OntologyInformation();
      this.languages = new HashSet();
      this.baseIris = new HashSet();
      this.iriGenerator = new VowlIriGenerator(this, (int)1);
      this.searcher = new VowlSearcher(this);
      this.generator = new VowlGenerator(this);
      this.thingProvider = new VowlThingProvider(this, this.searcher, this.generator);
      this.genericLiteral = new VowlLiteral(IRI.create("http://www.w3.org/2000/01/rdf-schema#Literal"));
      this.addDatatype(this.genericLiteral);
   }

	public OWLOntologyManager getOwlManager() {
		return this.owlManager;
	}

	public void setOwlManager(OWLOntologyManager owlManager) {
		this.owlManager = owlManager;
	}

	public Set<IRI> getBaseIris() {
		return this.baseIris;
	}

	public void addBaseIri(IRI iri) {
		if (!iri.toString().contains("http://owl2vowl.de")) {
			this.baseIris.add(iri);
		}
	}

	public VowlLiteral getGenericLiteral() {
		return this.genericLiteral;
	}

	public OntologyInformation getOntologyInformation() {
		return this.ontologyInformation;
	}

	public Map<IRI, TypeOfProperty> getTypeOfPropertyMap() {
		return this.typeOfPropertyMap;
	}

	public void addTypeOfProperty(TypeOfProperty property) {
		this.typeOfPropertyMap.put(property.getIri(), property);
	}

	public Map<IRI, VowlIndividual> getIndividualMap() {
		return this.individualMap;
	}

	public VowlThingProvider getThingProvider() {
		return this.thingProvider;
	}

	public VowlGenerator getGenerator() {
		return this.generator;
	}

	public VowlSearcher getSearcher() {
		return this.searcher;
	}

	public Map<IRI, AbstractEntity> getEntityMap() {
		return Collections.unmodifiableMap(this.entityMap);
	}

	public Map<IRI, AbstractDatatype> getDatatypeMap() {
		return Collections.unmodifiableMap(this.datatypeMap);
	}

	public Map<IRI, VowlObjectProperty> getObjectPropertyMap() {
		return Collections.unmodifiableMap(this.objectPropertyMap);
	}

	public Map<IRI, VowlDatatypeProperty> getDatatypePropertyMap() {
		return Collections.unmodifiableMap(this.datatypePropertyMap);
	}

	public Map<IRI, AbstractClass> getClassMap() {
		return Collections.unmodifiableMap(this.classMap);
	}

	public AbstractClass getClassForIri(IRI iri) {
		if (this.classMap.containsKey(iri)) {
			return (AbstractClass) this.classMap.get(iri);
		} else if (iri.toString().equals("http://www.w3.org/2002/07/owl#Thing")) {
			return new NullClass();
		} else {
			throw new IllegalStateException("Can\'t find class for passed iri: " + iri);
		}
	}

	public AbstractDatatype getDatatypeForIri(IRI iri) {
		if (this.datatypeMap.containsKey(iri)) {
			return (AbstractDatatype) this.datatypeMap.get(iri);
		} else {
			throw new IllegalStateException("Can\'t find datatype for passed iri: " + iri);
		}
	}

	public VowlObjectProperty getObjectPropertyForIri(IRI iri) {
		if (this.objectPropertyMap.containsKey(iri)) {
			return (VowlObjectProperty) this.objectPropertyMap.get(iri);
		} else {
			throw new IllegalStateException("Can\'t find object property for passed iri: " + iri);
		}
	}

	public VowlDatatypeProperty getDatatypePropertyForIri(IRI iri) {
		if (this.datatypePropertyMap.containsKey(iri)) {
			return (VowlDatatypeProperty) this.datatypePropertyMap.get(iri);
		} else {
			throw new IllegalStateException("Can\'t find datatype property for passed iri: " + iri);
		}
	}

	public AbstractEntity getEntityForIri(IRI iri) {
		if (this.entityMap.containsKey(iri)) {
			return (AbstractEntity) this.entityMap.get(iri);
		} else {
			throw new IllegalStateException("Can\'t find entity for passed iri: " + iri);
		}
	}

	public AbstractProperty getPropertyForIri(IRI iri) {
		AbstractEntity entity = this.getEntityForIri(iri);
		if (entity instanceof AbstractProperty) {
			return (AbstractProperty) entity;
		} else {
			throw new IllegalStateException("Can\'t find property for passed iri: " + iri);
		}
	}

	public AbstractNode getNodeForIri(IRI iri) {
		AbstractEntity entity = this.getEntityForIri(iri);
		if (entity instanceof AbstractNode) {
			return (AbstractNode) entity;
		} else {
			throw new IllegalStateException("Can\'t find node for passed iri: " + iri);
		}
	}

	public String getIdForIri(IRI iri) {
		return this.getIdForEntity(this.getEntityForIri(iri));
	}

	public String getIdForEntity(AbstractEntity entity) {
		if (!this.entityToId.containsKey(entity)) {
			this.entityToId.put(entity, "" + this.entityToId.keySet().size());
		}

		return (String) this.entityToId.get(entity);
	}

	public void addClass(AbstractClass vowlClass) {
		this.classMap.put(vowlClass.getIri(), vowlClass);
	}

	public void addDatatype(AbstractDatatype datatype) {
		this.datatypeMap.put(datatype.getIri(), datatype);
	}

	public void addObjectProperty(VowlObjectProperty prop) {
		this.objectPropertyMap.put(prop.getIri(), prop);
	}

	public void addDatatypeProperty(VowlDatatypeProperty prop) {
		this.datatypePropertyMap.put(prop.getIri(), prop);
	}

	public Set<String> getLanguages() {
		return Collections.unmodifiableSet(this.languages);
	}

	public void addLanguage(String language) {
		this.languages.add(language);
	}

	public IRI getNewIri() {
		return this.iriGenerator.generate();
	}

	public void addIndividual(VowlIndividual individual) {
		this.individualMap.put(individual.getIri(), individual);
	}

	public Collection<AbstractProperty> getProperties() {
		HashSet concat = new HashSet();
		concat.addAll(this.datatypePropertyMap.values());
		concat.addAll(this.objectPropertyMap.values());
		return Collections.unmodifiableSet(concat);
	}

	public OntologyMetric getMetrics() {
		return this.metrics;
	}

	public void setMetrics(OntologyMetric metrics) {
		this.metrics = metrics;
	}
}